/*
	Homepage: http://snipt.org
	Description: For use when interacting with the snipt.org API
	Version: 1.0
	Author: Dan Wasyluk

  	Copyright 2009 Dan Wasyluk / Snipt.org 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package org.snipt.api {
	import com.adobe.serialization.json.JSON;
	
	import flash.net.URLVariables;
	
	import mx.managers.CursorManager;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.InvokeEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	
	import org.snipt.api.events.AuthResultEvent;
	import org.snipt.api.events.DeleteSniptResultEvent;
	import org.snipt.api.events.EditSniptResultEvent;
	import org.snipt.api.events.GetSniptBoxResultEvent;
	import org.snipt.api.events.GetSniptLanguagesResultEvent;
	import org.snipt.api.events.GetSniptResultEvent;
	import org.snipt.api.events.GetSniptThemesResultEvent;
	import org.snipt.api.events.MakeSniptResultEvent;
	import org.snipt.api.events.SniptAPIFaultEvent;
	import org.snipt.api.events.SniptAPIResultEvent;
	
	public class SniptAPI extends HTTPService{
		
		public var apiURL:String;
		public var apiUser:String;
		public var apiPass:String;
		
		public var token:String;
		
		public var useWrapper:Boolean = false;
		
		//result event constants
		public static const AUTH_RESULT:String = "authResult";
		public static const SNIPT_API_FAULT:String = "sniptApiFault";
		public static const SNIPT_API_RESULT:String = "sniptApiResult";
		
		public static const GET_SNIPT_RESULT:String = "getSniptResult";
		public static const GET_SNIPT_BOX_RESULT:String = "getSniptBoxResult";
		public static const GET_SNIPT_LANGUAGES_RESULT:String = "getSniptLanguagesResult";
		public static const MAKE_SNIPT_RESULT:String = "makeSniptResult";
		public static const GET_SNIPT_THEMES_RESULT:String = "getSniptThemesResult";
		public static const EDIT_SNIPT_RESULT:String = "editSniptResult";
		public static const DELETE_SNIPT_RESULT:String = "deleteSniptResult";
		//end events ------
		
		public function SniptAPI(user:String = "", pass:String = "", url:String = "http://api.snipt.org/") {
			super();
			this.apiUser = user;
			this.apiPass = pass;
			this.apiURL = url;
			
			this.useWrapper = true; //REQUIRED FOR CUSTOM HANDLERS
			
			this.resultFormat = "text";
			
			this.addEventListener(FaultEvent.FAULT, this.handleFault);
			this.addEventListener(ResultEvent.RESULT, this.handleResult);
			this.addEventListener(InvokeEvent.INVOKE, this.handleInvoke);
		}
		
		//GENERIC HTTP HANDLERS
		private function handleInvoke(event:InvokeEvent):void {
			CursorManager.setBusyCursor();
		}
		
		private function handleFault(error:FaultEvent):void {
			trace("error: " + error);
			CursorManager.removeBusyCursor();
		}
		
		private function handleResult(rawResult:ResultEvent):void {
			trace("result: " + rawResult.result);
			var resultObject:Object = JSON.decode(rawResult.result.toString());
			
			if(this.useWrapper) { //if we are using a wrapper then decode the function name
				var functionName:String = resultObject.functionName;
				var result:Object = resultObject.result;
			}else{
				var result:Object = resultObject;
			}
			
			//see if an error occured
			if(result.hasOwnProperty("error")) {
				this.dispatchEvent(new SniptAPIFaultEvent(result));
				CursorManager.removeBusyCursor();
				return;
			}
			
			if(!this.useWrapper) { //if we arent using a wrapper, dispatch a generic result
				this.dispatchEvent(new SniptAPIResultEvent(result));
			}else{ //dispatch a custom event!
				switch(functionName) {
					case AuthResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new AuthResultEvent(result.token, result.twitterUser));
					
					case GetSniptResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new GetSniptResultEvent(result));
					break;
					
					case GetSniptBoxResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new GetSniptBoxResultEvent(result as Array));
					break;
					
					case GetSniptLanguagesResultEvent.FUNCTION_NAME: 
						this.dispatchEvent(new GetSniptLanguagesResultEvent(result as Array));
					break;
					
					case MakeSniptResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new MakeSniptResultEvent(result));
					break;
					
					case GetSniptThemesResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new GetSniptThemesResultEvent(result as Array));
					break;
					
					case EditSniptResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new EditSniptResultEvent(result));
					break;
					
					case DeleteSniptResultEvent.FUNCTION_NAME:
						this.dispatchEvent(new DeleteSniptResultEvent(result));
					break;
				}
			}
			
			
			CursorManager.removeBusyCursor();
		}
		
		//GENERAL FUNCTIONS
		private function appendCredentials(vars:URLVariables):URLVariables {
			vars.token = this.token;
			
			if(this.useWrapper) {
				vars.useWrapper = true;
			}
			
			return vars;
		}
		
		//SNIPT API FUNCTIONS
		public function auth():void {
			var urlVars:URLVariables = new URLVariables();
			urlVars.username = this.apiUser;
			urlVars.password = this.apiPass;
			if(this.useWrapper) {
				urlVars.useWrapper = true;
			}
			
			this.url = this.apiURL + "auth/";
			trace("auth: " + this.url);
			this.method = "GET";
			this.send(urlVars);
		}
		
		public function getSnipt(sniptID:String):void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
			urlVars.ID = sniptID;
			
			this.url = this.apiURL + "getSnipt/";
			
			trace("getSnipt: " + this.url);
			this.method = "GET";
			this.send(urlVars);
		}
		
		public function getSniptBox(username:String):void {
			
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
			urlVars.username = username;
			
			this.url = this.apiURL + "getSniptBox/";
			
			trace("getSniptBox: " + this.url);
			this.method = "GET";
			this.send(urlVars);
		}
		
		public function getLanguages():void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
		
			this.url = this.apiURL + "getLanguages/";
			
			trace("getLanguages: " + this.url);
			this.method = "GET";
			this.send(urlVars);
		}
		
		public function getThemes():void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
		
			this.url = this.apiURL + "getThemes/";
			
			trace("getThemes: " + this.url);
			this.method = "GET";
			this.send(urlVars);
		}
		
		public function makeSnipt(title:String, lang:String, snippet:String, showNums:Boolean = false, isPrivate:Boolean = false, addToBox:Boolean = false, themeID:Number = 1):void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
			trace("make(" + title + ", " + snippet + ", " + lang + ")");
			urlVars.title = title;
			urlVars.content = snippet;
			urlVars.language = lang;
			urlVars.isPrivate = isPrivate;
			urlVars.showNums = showNums;
			urlVars.themeID = themeID;
			
			if(addToBox) {
				urlVars.twitterUser = this.apiUser;
			}
			
			//urlVars.twitterUser
			
			this.url = this.apiURL + "makeSnipt/";
			trace("makeSnipt: " + this.url);
			this.method = "POST";
			this.send(urlVars);
		}
		
		public function editSnipt(sniptID:String, title:String, lang:String, snippet:String, showNums:Boolean = false, isPrivate:Boolean = false, addToBox:Boolean = false, themeID:Number = 1):void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
			
			urlVars.ID = sniptID;
			urlVars.title = title;
			urlVars.content = snippet;
			urlVars.language = lang;
			urlVars.isPrivate = isPrivate;
			urlVars.showNums = showNums;
			urlVars.themeID = themeID;
			
			if(addToBox) {
				urlVars.twitterUser = this.apiUser;
			}
			
			//urlVars.twitterUser
			
			this.url = this.apiURL + "editSnipt/";
			trace(sniptID +" | editSnipt: " + this.url);
			this.method = "POST";
			this.send(urlVars);
		}
		
		public function deleteSnipt(sniptID:String):void {
			var urlVars:URLVariables = new URLVariables();
			urlVars = this.appendCredentials(urlVars);
			
			urlVars.ID = sniptID;
			
			this.url = this.apiURL + "deleteSnipt/";
			trace(sniptID +" | editSnipt: " + this.url);
			this.method = "POST";
			this.send(urlVars);
		}
	}
}